#include <cstdio>
#include <cstdlib>
#include "element_generique.hpp"

using namespace std;

// INT

void initInt(Elem &e, const int i) {
    e = new int;
    *(reinterpret_cast<int*> (e)) = i;
}

void initInt(Elem &e1, const Elem e2) {
    initInt(e1, *(reinterpret_cast<int *> (e2)));
}

void affectationInt(Elem &e1, const Elem e2) {
    if (e1 != e2) {
        *(reinterpret_cast<int *> (e1)) = *(reinterpret_cast<int *> (e2));
    }
}

void afficheInt(const Elem &e) {
    printf("%d", *(reinterpret_cast<int*> (e)));
}

int compareInt(const Elem &e1, const Elem &e2) {
    return (*(reinterpret_cast<int *> (e1)) - *(reinterpret_cast<int *> (e2)));
}

void testamentInt(Elem &e) {
    delete reinterpret_cast<int *> (e);
}

//DOUBLE

void initDouble(Elem &e, const double i) {
    e = new double;
    *(reinterpret_cast<double*> (e)) = i;
}

void initDouble(Elem &e1, Elem e2) {
    initDouble(e1, *(reinterpret_cast<double*> (e2)));
}

void affectationDouble(Elem &e1, const Elem e2) {
    if (e1 != e2) {
        *(reinterpret_cast<double *> (e1)) = *(reinterpret_cast<double*> (e2));
    }
}

void afficheDouble(const Elem &e) {
    printf("%f ", *(reinterpret_cast<double*> (e)));
}

int compareDouble(const Elem &e1, const Elem &e2) {
    if (*(reinterpret_cast<int *> (e1)) > *(reinterpret_cast<double*> (e2))) {
        return 1;
    } else if (*(reinterpret_cast<int *> (e1)) < *(reinterpret_cast<double*> (e2))) {
        return -1;
    } else {
        return 0;
    }
}

void testamentDouble(Elem &e) {
    delete reinterpret_cast<double*> (e);
}

// NOEUD

void initNoeudGenerique(Elem &e, const Noeud &n, bool verbose) {
    e = new Noeud;
    initNoeud(*(reinterpret_cast<Noeud*> (e)), n);
}

void initNoeudGenerique(Elem &e1, const Elem e2, bool verbose) {
    e1 = new Noeud;
    initNoeud(*(reinterpret_cast<Noeud*> (e1)), *(reinterpret_cast<Noeud*> (e2)));
}

void affectationNoeud(Elem &e1, const Elem e2) {
    copieNoeud(*(reinterpret_cast<Noeud*> (e1)), *(reinterpret_cast<Noeud*> (e2)));
}

int comparaisonNoeud(const Elem &e1, const Elem &e2) {
    return (compNoeud(*(reinterpret_cast<Noeud*> (e1)), *(reinterpret_cast<Noeud*> (e2))));
}

void afficheNoeud(const Elem &e) {
    afficherNoeud(*(reinterpret_cast<Noeud*> (e)));
}

void testamentNoeudGenerique(Elem &e) {
    testamentNoeud(*(reinterpret_cast<Noeud*> (e)));
    delete reinterpret_cast<Noeud*> (e);
}

// ARC

void initArcGenerique(Elem &e, const Arc n, bool verbose) {
    initArc(*(reinterpret_cast<Arc*> (e)), n);
}

void initArcGenerique(Elem &e1, const Elem e2, bool verbose) {

    if (verbose) {
        cout << "arc à init" << endl;
        //afficherArc(*(reinterpret_cast<Arc*> (e1)));
        cout << "arc à copier" << endl;
        afficherArc(*(reinterpret_cast<Arc*> (e2)));
        cout << endl;
    }

    initArc(*(reinterpret_cast<Arc*> (e1)), *(reinterpret_cast<Arc*> (e2)));
}

void affectationArc(Elem &e1, const Elem e2) {
    copieArc(*(reinterpret_cast<Arc*> (e1)), *(reinterpret_cast<Arc*> (e2)));
}

int comparaisonArc(const Elem &e1, const Elem &e2) {
    return compArc(*(reinterpret_cast<Arc*> (e1)), *(reinterpret_cast<Arc*> (e2)));
}

void afficheArc(const Elem &e) {
    afficherArc(*(reinterpret_cast<Arc*> (e)));
}

void testamentArc(Elem &e) {
    testamentArc(*(reinterpret_cast<Arc*> (e)));
    delete reinterpret_cast<Arc*> (e);
}
